package com.atguigu.es.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.MaxAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.xcontent.XContentType;

import javax.swing.text.Highlighter;
import java.io.IOException;

/**
 * @ClassName ESTestDoc
 * @Description TODO
 * @Author Lambert
 * @Date 2022/6/30 19:32
 * @Version 1.0
 **/
public class ESTestDoc {
    public static void main(String[] args) throws IOException {
        RestHighLevelClient esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
        //插入文档
//        IndexRequest request = new IndexRequest("user").id("1001");
////        request.index("user").id("1001");
//        User user = new User("zhangsan","男","13748794432");
////        //向ES插入数据必须将数据转换为JSON格式
//        ObjectMapper mapper = new ObjectMapper();
//        String userJson = mapper.writeValueAsString(user);
//        request.source(userJson, XContentType.JSON);//请求体
//        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
//        System.out.println(response.getResult());//CREATED

        //修改文档
//        UpdateRequest request = new UpdateRequest("user", "1001");
//        request.doc(XContentType.JSON, "sex","女");
//        UpdateResponse updateResponse = esClient.update(request, RequestOptions.DEFAULT);
//        System.out.println(updateResponse.getResult());//UPDATED

        //查询文档
//        GetRequest request = new GetRequest();
//        request.index("user").id("1001");
//        GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
//        System.out.println(response.getSourceAsString());//{"name":"zhangsan","sex":"女","age":30}


        //删除文档
//        DeleteRequest request = new DeleteRequest();
//        request.index("user").id("1001");
//        DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT);
//        System.out.println(response.toString());//DeleteResponse[index=user,type=_doc,id=1001,version=3,result=deleted,shards=ShardInfo{total=2, successful=1, failures=[]}]

        //批量新增文档
//        BulkRequest request = new BulkRequest();
//        request.add(new IndexRequest().index("user").id("1001").source(XContentType.JSON,"name","zhangsan","tel","13748794433","sex","男"));
//        request.add(new IndexRequest().index("user").id("1002").source(XContentType.JSON,"name","lisi","tel","13748794434","sex","女"));
//        request.add(new IndexRequest().index("user").id("1003").source(XContentType.JSON,"name","wangwu","tel","13748794435","sex","男"));
//        request.add(new IndexRequest().index("user").id("1004").source(XContentType.JSON,"name","wangwu1","tel","13748794436","sex","女"));
//        request.add(new IndexRequest().index("user").id("1005").source(XContentType.JSON,"name","wangwu2","tel","13748794437","sex","男"));
//        request.add(new IndexRequest().index("user").id("1006").source(XContentType.JSON,"name","wangwu3","tel","13748794438","sex","男"));
//        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
//        System.out.println(response.getTook());
//        System.out.println(response.getItems());

        //批量删除文档
//        BulkRequest request = new BulkRequest();
//        request.add(new DeleteRequest().index("user").id("1001"));
//        request.add(new DeleteRequest().index("user").id("1002"));
//        request.add(new DeleteRequest().index("user").id("1003"));
//        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
//        System.out.println(response.getTook());
//        System.out.println(response.getItems());

        //高级查询：查询索引中的全部数据
//        SearchRequest request = new SearchRequest();
//
//        request.indices("user");
//        request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
//
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());//6 hits
//        System.out.println(response.getTook());//2ms
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"zhangsan","age":30,"sex":"男"}
//            //{"name":"lisi","age":30,"sex":"女"}
//            //{"name":"wangwu","age":40,"sex":"男"}
//            //{"name":"wangwu1","age":40,"sex":"女"}
//            //{"name":"wangwu2","age":50,"sex":"男"}
//            //{"name":"wangwu3","age":50,"sex":"男"}
//        }
        //高级查询：条件查询
//        SearchRequest request = new SearchRequest();
//
//        request.indices("user");
//        request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("sex", "男")));
//
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();//2 hits
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"zhangsan","tel":"13748794433","sex":"男"}
//            //{"name":"wangwu","tel":"13748794435","sex":"男"}
//            //{"name":"wangwu2","tel":"13748794437","sex":"男"}
//            //{"name":"wangwu3","tel":"13748794438","sex":"男"}
//        }
        //分页查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.from(0);//从第几个开始查
//        builder.size(2);//页大小
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//        }
        //排序查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        builder.from(0);//从第几个开始查
//        builder.size(2);//页大小
//        builder.sort("age", SortOrder.DESC);
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"wangwu1","tel":"13748794436","sex":"女","age":"40"}
//            //{"name":"wangwu3","tel":"13748794438","sex":"男","age":34}
//        }
        //过滤字段
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//        String [] excludes = {"tel"};//排除 排除tel：显示sex,name,age字段
//        String [] includes = {};//包含name,age->显示name,age字段
//        builder.fetchSource(includes,excludes);
////        builder.from(0);//从第几个开始查
////        builder.size(2);//页大小
//        builder.sort("age", SortOrder.DESC);
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            {"sex":"女","name":"wangwu1","age":"40"}
//            {"sex":"男","name":"wangwu3","age":34}
//            {"sex":"男","name":"wangwu2","age":"25"}
//            {"sex":"女","name":"lisi","age":"19"}
//            {"sex":"男","name":"zhangsan","age":"18"}
//            {"sex":"男","name":"wangwu","age":"14"}
//        }
        //组合查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//
//        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
////        boolQueryBuilder.must(QueryBuilders.matchQuery("age",25));
////        boolQueryBuilder.must(QueryBuilders.matchQuery("sex","男"));
//        boolQueryBuilder.should(QueryBuilders.matchQuery("age",40));
//        boolQueryBuilder.should(QueryBuilders.matchQuery("age",18));
//        builder.query(boolQueryBuilder);
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"wangwu2","tel":"13748794437","sex":"男","age":"25"}
//        }
        //范围查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//
//        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
//        rangeQueryBuilder.gte(20);//>=20
//        rangeQueryBuilder.lte(40);//<=40
//
//
//        builder.query(rangeQueryBuilder);
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"wangwu1","tel":"13748794436","sex":"女","age":"40"}
//            //{"name":"wangwu2","tel":"13748794437","sex":"男","age":"25"}
//            //{"name":"wangwu3","tel":"13748794438","sex":"男","age":34}
//        }
        //模糊查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//
//        builder.query(QueryBuilders.fuzzyQuery("name","wangwu").fuzziness(Fuzziness.ONE));//能接受一个字符的偏差
//
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getSourceAsString());
//            //{"name":"wangwu","tel":"13748794435","sex":"男","age":"14"}
//            //{"name":"wangwu1","tel":"13748794436","sex":"女","age":"40"}
//            //{"name":"wangwu2","tel":"13748794437","sex":"男","age":"25"}
//            //{"name":"wangwu3","tel":"13748794438","sex":"男","age":34}
//        }

        //高亮查询
//        SearchRequest request = new SearchRequest();
//        request.indices("user");
//        SearchSourceBuilder builder = new SearchSourceBuilder();
//        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "zhangsan");
//
//        HighlightBuilder highlightBuilder = new HighlightBuilder();
//        highlightBuilder.preTags("<font color='red'>");
//        highlightBuilder.postTags("</font>");
//        highlightBuilder.field("name");
//        builder.highlighter(highlightBuilder);
//
//        builder.query(termQueryBuilder);
//        request.source(builder);
//        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
//        SearchHits hits = response.getHits();
//        System.out.println(hits.getTotalHits());
//        for (SearchHit hit : hits) {
//            System.out.println(hit.getHighlightFields());
//            //{name=[name], fragments[[<font color='red'>zhangsan</font>]]}
//            System.out.println(hit.getSourceAsString());
//            //{"name":"zhangsan","tel":"13748794433","sex":"男","age":"18"}
//        }
        //聚合查询-最大值查询&分组查询
        SearchRequest request = new SearchRequest();
        request.indices("user");
        SearchSourceBuilder builder = new SearchSourceBuilder();

        //最大值查询
//        AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age");

        //分组查询
        AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
        builder.aggregation(aggregationBuilder);

        request.source(builder);
        SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
        System.out.println(response);
        //年龄最大值查询：...."aggregations":{"max#maxAge":{"value":40.0}}
        //年龄分组查询：...."buckets":[{"key":14,"doc_count":1},{"key":18,"doc_count":1},{"key":19,"doc_count":1},{"key":25,"doc_count":1},{"key":34,"doc_count":1},{"key":40,"doc_count":1}]}}
        SearchHits hits = response.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            //{"name":"zhangsan","tel":"13748794433","sex":"男","age":"18"}
        }
        esClient.close();
    }
}
